type JSDynamicObject = any;
const mySymbol : symbol = Symbol ('mySymbol');
console.log (typeof mySymbol);
var s : string = mySymbol.toString ();
console.log (s);
const globalSymbol : symbol = Symbol.for ('globalSymbol');
const globalSymbol2 : symbol = Symbol.for ('globalSymbol');
console.log (globalSymbol === globalSymbol2);
var kf : string | undefined = Symbol.keyFor (globalSymbol);
console.log (kf);
var s1 : symbol = Symbol.hasInstance;
class MyClass {
    static [s1] (instance : any) : any {
        return typeof instance === 'object';
    }
}
console.log ({} instanceof MyClass);
const arr1 : number [] = [1, 2, 3];
const arr2 : number [] = [4, 5, 6];
var s2 : symbol = Symbol.isConcatSpreadable;
console.log (arr1.concat (arr2));
const myObj : JSDynamicObject = {
    [Symbol.iterator] () : Iterator <symbol> {
        let i : number = 0;
        const values : number [] = [1, 2, 3];
        return {
            next () : JSDynamicObject {
                if (i >= values.length) {
                    return {
                        done : true
                    };
                }
                return {
                    value : values [i ++],
                    done : false
                };
            }
        };
    }
};
for (const value of myObj) {
    console.log (value);
}
var s3 : symbol = Symbol.match;
class MyMatcher {
    [s3] (str : any) : any {
        return str.indexOf ('hello') !== - 1;
    }
}
class MyReplacer {
    [Symbol.replace] (str : any, newStr : any) : any {
        return str.replace (/hello/g, newStr);
    }
}
console.log ('hello world'.replace (new MyReplacer (), 'hi'));
class MySearcher {
    [Symbol.search] (str : any) : any {
        return str.indexOf ('world');
    }
}
console.log ('hello world'.search (new MySearcher ()));
class MyArray extends Array {
    static get [Symbol.species] () : any {
        return Array;
    }
}
const myArr : number [] = [1, 2, 3];
const mappedArr : any = myArr.map ((x : any) : number => {
        return x * 2;
    });
console.log (mappedArr instanceof MyArray);
console.log (mappedArr instanceof Array);
class MySplitter {
    [Symbol.split] (str : any) : any {
        return str.split (' ');
    }
}
console.log ('hello world'.split (new MySplitter ()));
const myObj2 : JSDynamicObject = {
    [Symbol.toPrimitive] (hint : string) : any {
        if (hint === 'number') {
            return 123;
        }
        if (hint === 'string') {
            return 'hello';
        }
        return true;
    }
};
console.log ((+ myObj2));
console.log (`${myObj2}`);
console.log (myObj2 ? 'truthy' : 'falsy');
class MyClass2 {
    get [Symbol.toStringTag] () : any {
        return 'MyClass2';
    }
}
const myObj3 : MyClass2 = new MyClass2 ();
console.log (Object.prototype.toString.call (myObj3));
